package com.example.behaviour.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.behaviour.config.SpringUtils;
import com.example.behaviour.mapper.ApUserMsgListMapper;
import com.example.behaviour.message.AckResponseMessage;
import com.example.behaviour.message.ChatRequestMessage;
import com.example.behaviour.message.ChatResponseMessage;
import com.example.behaviour.message.LatestMsgListResponseMessage;
import com.example.behaviour.pojos.ApUserMsgList;
import com.example.behaviour.pojos.Message;
import com.example.behaviour.session.SessionFactory;
import com.example.common.constants.MessageConstants;
import com.example.common.redis.RedisCache;
import com.example.model.user.pojos.ApUser;
import com.example.user.mapper.ApUserMapper;
import io.netty.channel.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class ChatRequestMessageHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    private static RedisCache redisCache;

    private static ApUserMsgListMapper apUserMsgListMapper;

    private static ApUserMapper apUserMapper;

    @Override
    public void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        log.info("执行到了LoginRequestMessageHandler");

        apUserMsgListMapper = SpringUtils.getBean(ApUserMsgListMapper.class);
        redisCache = SpringUtils.getBean(RedisCache.class);
        apUserMapper = SpringUtils.getBean(ApUserMapper.class);

        JSONObject jsonObject = JSONObject.parseObject(msg.text());
        Message message = JSONObject.toJavaObject(jsonObject,Message.class);
        if(message.getUsername() == null){
            return;
        }
        message.setId(UUID.randomUUID().toString());
        message.setCreatedTime(new Date());
//        String to = message.getTo();
//        System.out.println("map to "+to);
//        ChannelHandlerContext channel = SessionFactory.getSession().getChannel(to);
//        System.out.println("channel "+channel);
//        System.out.println("message "+message);

        // 初始化时获取最新消息列表
        if("-1".equals(message.getAckMsgId())){
            Channel channel = null;
            try{
                channel = SessionFactory.getSession().getChannel(message.getTo()).channel();
            }catch (Exception e){

            }

//            updateFrom_SEND_DELIVERED_RedisData(redisCache,message,MessageConstants.DELIVERED,"已送达");
            TextWebSocketFrame fromLatestData = getFromLatestData(redisCache, message);
            fromLatestData.retain();
            ctx.writeAndFlush(fromLatestData);




//            updateTo_DELIVERED_READ_RedisData(redisCache,message,MessageConstants.READ,"已读");
//            if(channel != null){
//                TextWebSocketFrame toLatestData1 = getLatestData(redisCache, message);
//                toLatestData1.retain();
//                channel.writeAndFlush(toLatestData1);
//            }

            //清除小红点
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userName",message.getUsername());
            queryWrapper.eq("friendName",message.getTo());
            ApUserMsgList apUserMsgList = apUserMsgListMapper.selectOne(queryWrapper);
            apUserMsgList.setMsgNum(0);
            apUserMsgListMapper.updateById(apUserMsgList);

//            QueryWrapper queryWrapper2 = new QueryWrapper<>();
//            queryWrapper2.eq("userName",message.getTo());
//            queryWrapper2.eq("friendName",message.getUsername());
//            ApUserMsgList apUserMsgList2 = apUserMsgListMapper.selectOne(queryWrapper2);

//            QueryWrapper queryWrapper3 = new QueryWrapper<>();
//            queryWrapper3.eq("userName",message.getUsername());
//            queryWrapper3.eq("friendName",message.getTo());
//            ApUserMsgList apUserMsgList3 = apUserMsgListMapper.selectOne(queryWrapper3);

//            apUserMsgList2.setMsgNum(0);
//            apUserMsgListMapper.updateById(apUserMsgList2);

            return;
        }

        //送达后缓存到redis
        insertToRedisData(redisCache,message,apUserMapper);
        insertFromRedisData(redisCache,message,MessageConstants.SENT,"已发送",apUserMapper);

//        TextWebSocketFrame webSocketFrame = new TextWebSocketFrame("返回一个最新消息的列表");
        TextWebSocketFrame webSocketFrame_from = getFromLatestData(redisCache,message);
        webSocketFrame_from.retain();
        ctx.writeAndFlush(webSocketFrame_from);
        Channel channel = null;
        try {
            channel = SessionFactory.getSession().getChannel(message.getTo()).channel();
        }catch (Exception e){

        }

        if(channel != null){
            TextWebSocketFrame webSocketFrame_to = getToLatestData(redisCache,message);
            webSocketFrame_to.retain();
            channel.writeAndFlush(webSocketFrame_to);
        }else {
            log.info("用户不在线1");
        }





//        updateFrom_SEND_DELIVERED_RedisData(redisCache,message,MessageConstants.DELIVERED,"已送达");
        try {
            TextWebSocketFrame webSocketFrame_From3 = getFromLatestData(redisCache,message);
            webSocketFrame_From3.retain();
            ctx.writeAndFlush(webSocketFrame_From3);

            ChannelHandlerContext ctx2 = SessionFactory.getSession().getChannel(message.getFrom());
            ChannelHandlerContext ctx3 = SessionFactory.getSession().getChannel(message.getTo());
            if(ctx2 != null && ctx3 != null){
                Channel channel2 = ctx2.channel();
                //已读回执
//                updateFrom_DELIVERED_READ_RedisData(redisCache,message,MessageConstants.READ,"已读");

                TextWebSocketFrame webSocketFrame_to2 = getFromLatestData(redisCache,message);
                webSocketFrame_to2.retain();
                channel2.writeAndFlush(webSocketFrame_to2);

//                updateMsgListLatestMsg(message);
                log.info("用户在线2");
            }else{

            }
            log.info("执行到这里了 {}",SessionFactory.getSession().toString());
            if(ctx3 != null){
                updateMgsListLatestMsgWhileChannelNotNull(message);
            }else{
                updateMsgListLatestMsgWhileChannelIsNull(message);
            }

        }catch (Exception e){
            e.printStackTrace();
        }




//        }



        msg.retain();
        ctx.fireChannelRead(msg);

    }

    public void updateMgsListLatestMsgWhileChannelNotNull(Message message){
        log.info("updateMgsListLatestMsgWhileChannelNotNull message {}",message.toString());

        //接收方
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userName",message.getTo());  //admin
        queryWrapper.eq("friendName",message.getUsername());  //rjl
        ApUserMsgList apUserMsgList = apUserMsgListMapper.selectOne(queryWrapper);
        if(message.getContentType() == 2){
            apUserMsgList.setContent("图片消息");
        }else if(message.getContentType() == 1){
            apUserMsgList.setContent(message.getContent());
        }else if(message.getContentType() == 3){
            apUserMsgList.setContent("视频消息");
        }else if(message.getContentType() == 4){
            apUserMsgList.setContent("语音消息");
        }

        apUserMsgList.setCreatedTime(message.getCreatedTime());
        apUserMsgList.setContentType(message.getContentType());
        apUserMsgList.setMsgNum(0);
        apUserMsgList.setUserName(message.getTo());
        apUserMsgList.setFriendName(message.getUsername());
        apUserMsgList.setCreatedTime(new Date());
        apUserMsgListMapper.updateById(apUserMsgList);

        //发送方
        QueryWrapper queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("userName",message.getUsername());
        queryWrapper2.eq("friendName",message.getTo());
        ApUserMsgList apUserMsgList2 = apUserMsgListMapper.selectOne(queryWrapper2);
        if(message.getContentType() == 2){
            apUserMsgList2.setContent("图片消息");
        }else if(message.getContentType() == 1){
            apUserMsgList2.setContent(message.getContent());
        }else if(message.getContentType() == 3){
            apUserMsgList2.setContent("视频消息");
        }else if(message.getContentType() == 4){
            apUserMsgList2.setContent("语音消息");
        }
        apUserMsgList2.setCreatedTime(message.getCreatedTime());
        apUserMsgList2.setContentType(message.getContentType());
        apUserMsgList2.setMsgNum(0);
        apUserMsgList2.setUserName(message.getUsername());
        apUserMsgList2.setFriendName(message.getTo());
        apUserMsgList2.setCreatedTime(new Date());
        apUserMsgListMapper.updateById(apUserMsgList2);
    }

    public void updateMsgListLatestMsgWhileChannelIsNull(Message message){
        log.info("updateMsgListLatestMsgWhileChannelIsNull message {}",message.toString());
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userName",message.getTo());
        queryWrapper.eq("friendName",message.getUsername());
        ApUserMsgList apUserMsgList = apUserMsgListMapper.selectOne(queryWrapper);
        if(apUserMsgList == null){

        }
        //接收方
        if(message.getContentType() == 2){
            apUserMsgList.setContent("图片消息");
        }else if(message.getContentType() == 1){
            apUserMsgList.setContent(message.getContent());
        }else if(message.getContentType() == 3){
            apUserMsgList.setContent("视频消息");
        }else if(message.getContentType() == 4){
            apUserMsgList.setContent("语音消息");
        }
        apUserMsgList.setCreatedTime(message.getCreatedTime());
        apUserMsgList.setContentType(message.getContentType());
        apUserMsgList.setMsgNum(apUserMsgList.getMsgNum()+1);
        apUserMsgListMapper.updateById(apUserMsgList);

        //发送方
        QueryWrapper queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("userName",message.getUsername());
        queryWrapper2.eq("friendName",message.getTo());
        ApUserMsgList apUserMsgList2 = apUserMsgListMapper.selectOne(queryWrapper2);
        if(message.getContentType() == 2){
            apUserMsgList2.setContent("图片消息");
        }else if(message.getContentType() == 1){
            apUserMsgList2.setContent(message.getContent());
        }else if(message.getContentType() == 3){
            apUserMsgList2.setContent("视频消息");
        }else if(message.getContentType() == 4){
            apUserMsgList2.setContent("语音消息");
        }
        apUserMsgList2.setCreatedTime(message.getCreatedTime());
        apUserMsgList2.setContentType(message.getContentType());
        apUserMsgList2.setMsgNum(0);
        apUserMsgListMapper.updateById(apUserMsgList2);
    }

    public TextWebSocketFrame getLatestData(RedisCache redisCache,Message message){
        String new_listJson = redisCache.get(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo());
        if(new_listJson == null || new_listJson.length() == 0){
            new_listJson = redisCache.get(MessageConstants.FROM + message.getTo() + MessageConstants.TO + message.getUsername());
        }
        List<Message> msgList = JSON.parseObject(new_listJson, new TypeReference<List<Message>>(){});
//        log.info("getFromLatestData {}", Arrays.toString(msgList.toArray()));
        LatestMsgListResponseMessage latestMsgListResponseMessage = new LatestMsgListResponseMessage();
        latestMsgListResponseMessage.setMessageList(msgList);
        TextWebSocketFrame frame1 = new TextWebSocketFrame(JSON.toJSONString(latestMsgListResponseMessage));

        return frame1;
    }


    public TextWebSocketFrame getFromLatestData(RedisCache redisCache,Message message){
        String new_listJson = redisCache.get(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo());
        List<Message> msgList = JSON.parseObject(new_listJson, new TypeReference<List<Message>>(){});
//        log.info("getFromLatestData {}", Arrays.toString(msgList.toArray()));
        LatestMsgListResponseMessage latestMsgListResponseMessage = new LatestMsgListResponseMessage();
        latestMsgListResponseMessage.setMessageList(msgList);
        TextWebSocketFrame frame1 = new TextWebSocketFrame(JSON.toJSONString(latestMsgListResponseMessage));

        return frame1;
    }

    public TextWebSocketFrame getToLatestData(RedisCache redisCache,Message message){
        String new_listJson = redisCache.get(MessageConstants.FROM + message.getTo() + MessageConstants.TO + message.getUsername());
        List<Message> msgList = JSON.parseObject(new_listJson, new TypeReference<List<Message>>(){});
        LatestMsgListResponseMessage latestMsgListResponseMessage = new LatestMsgListResponseMessage();
        latestMsgListResponseMessage.setMessageList(msgList);
        TextWebSocketFrame frame1 = new TextWebSocketFrame(JSON.toJSONString(latestMsgListResponseMessage));

        return frame1;
    }

    public void insertToRedisData(RedisCache redisCache,Message message,ApUserMapper apUserMapper){
        String listJson = redisCache.get(MessageConstants.FROM + message.getTo() + MessageConstants.TO + message.getFrom());
        List<Message> messageList = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",message.getFrom());
        ApUser apUser = apUserMapper.selectOne(queryWrapper);
        message.setImage(apUser.getImage());

        if (listJson == null || "[]".equals(listJson) || listJson.length() == 0) {
            messageList.add(message);
        } else {
            messageList = JSON.parseArray(listJson, Message.class);
            messageList.add(message);
        }
        log.info("插入缓存 messageList {}", Arrays.toString(messageList.toArray()));
        redisCache.set(MessageConstants.FROM + message.getTo() + MessageConstants.TO + message.getFrom(),JSON.toJSONString(messageList));
    }
    public void insertFromRedisData(RedisCache redisCache,Message message,Integer msgType,String typeInfo,ApUserMapper apUserMapper) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",message.getFrom());
        ApUser apUser = apUserMapper.selectOne(queryWrapper);
        message.setImage(apUser.getImage());

        String listJson = redisCache.get(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo());
        List<Message> messageList = new ArrayList<>();
        message.setMsgType(msgType);
        message.setTypeInfo(typeInfo);
        message.setImage(apUser.getImage());
        if (listJson == null || "[]".equals(listJson) || listJson.length() == 0) {
            messageList.add(message);
        } else {
            messageList = JSON.parseArray(listJson, Message.class);
            messageList.add(message);
        }
        log.info("插入缓存 messageList {}", Arrays.toString(messageList.toArray()));
        redisCache.set(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo(),JSON.toJSONString(messageList));

    }

    public void updateFrom_DELIVERED_READ_RedisData(RedisCache redisCache,Message message,Integer msgType,String typeInfo){
        log.info("更新From_DELIVERED_READ缓存 message {}",message.toString());

        List<Message> messageList;

        String listJson = redisCache.get(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo());
        if (listJson == null || "[]".equals(listJson) || listJson.length() == 0) {
            return;
        } else {
            messageList = JSON.parseArray(listJson, Message.class);
            messageList = messageList.stream().map(item -> {
                if(item.getUsername().equals(message.getUsername())){
                    item.setMsgType(msgType);
                    item.setTypeInfo(typeInfo);
                }

//                log.info("item {}",item);
                return item;
            }).collect(Collectors.toList());
        }
        redisCache.set(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo(),JSON.toJSONString(messageList));
    }

    public void updateFrom_SEND_DELIVERED_RedisData(RedisCache redisCache,Message message,Integer msgType,String typeInfo) {

        log.info("更新From_SEND_DELIVERED缓存 message {}",message.toString());

        List<Message> messageList;

        String listJson = redisCache.get(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo());
        if (listJson == null || "[]".equals(listJson) || listJson.length() == 0) {
            return;
        } else {
            messageList = JSON.parseArray(listJson, Message.class);
            messageList = messageList.stream().map(item -> {
                if (Objects.equals(item.getUsername(), message.getUsername())) {
                    item.setMsgType(msgType);
                    item.setTypeInfo(typeInfo);
//                    log.info("item {}",item);
                }
                return item;
            }).collect(Collectors.toList());
        }
        redisCache.set(MessageConstants.FROM + message.getUsername() + MessageConstants.TO + message.getTo(),JSON.toJSONString(messageList));
    }



}
